package com.probiz.estore.product.service.impl;

import java.math.BigDecimal;
import java.util.List;

import com.probiz.estore.common.helper.ConfigUtil;
import com.probiz.estore.common.model.customer.Customer;
import com.probiz.estore.common.model.customer.ReviewEligibility;
import com.probiz.estore.common.model.customer.ShopPoint;
import com.probiz.estore.common.model.product.Product;
import com.probiz.estore.common.model.product.ProductReview;
import com.probiz.estore.common.model.product.ProductStat;
import com.probiz.estore.core.search.SearchCriteria;
import com.probiz.estore.core.service.impl.GenericManagerImpl;
import com.probiz.estore.customer.dao.ReviewEligibilityDao;
import com.probiz.estore.customer.service.CustomerManager;
import com.probiz.estore.customer.service.ShopPointManager;
import com.probiz.estore.product.dao.ProductReviewDao;
import com.probiz.estore.product.model.ProductReviewSearchCriteria;
import com.probiz.estore.product.service.ProductManager;
import com.probiz.estore.product.service.ProductReviewManager;
import com.probiz.estore.product.service.ProductStatManager;


/**
 * Manager implementation for ProductReview, responsible for business processing, and communicate between web and persistence layer.
 */
public class ProductReviewManagerImpl extends GenericManagerImpl<ProductReview> implements ProductReviewManager {

    private ProductStatManager productStatManager = null;
	private ProductReviewDao productReviewDao = null;
	private ProductManager productManager = null;
	private ReviewEligibilityDao  reviewEligibilityDao =null;
	private ShopPointManager  shopPointManager = null;
	private CustomerManager  customerManager = null;

	/**
	 * @param productReviewDao   the productReviewDao to set
	 */
	public void setProductReviewDao(ProductReviewDao productReviewDao) {
		this.productReviewDao = productReviewDao;
	}
	
	public void setProductStatManager(ProductStatManager productStatManager) {
		this.productStatManager = productStatManager;
	}
	
	

	public void setProductManager(ProductManager productManager) {
		this.productManager = productManager;
	}
	
	
	public void setReviewEligibilityDao(ReviewEligibilityDao reviewEligibilityDao) {
		this.reviewEligibilityDao = reviewEligibilityDao;
	}
	

	public void setShopPointManager(ShopPointManager shopPointManager) {
		this.shopPointManager = shopPointManager;
	}

	
	public void setCustomerManager(CustomerManager customerManager) {
		this.customerManager = customerManager;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#init()
	 */
	@Override
	protected void initManager() {
		dao = productReviewDao;
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#deleteFully(com.probiz.estore.common.model.product.ProductReview)
	 */
	public void deleteFully(ProductReview productReview){
		//先删除评论再统计
		this.delete(productReview);
		if(productReview.getParent() == null){
			//case:评论
			if(productReview.getStatus().equals(ProductReview.STATUS_SHOW)){
				updateReviewCountAndScore(productReview.getProductId(),-1,-1);
			}else{
				updateReviewCountAndScore(productReview.getProductId(),-1,0);
			}
		}else{
			//case:回复
			if(productReview.getStatus().equals(ProductReview.STATUS_SHOW)){
				updateReviewReplyCount(productReview.getParent(),-1,-1);
			}else{
				updateReviewReplyCount(productReview.getParent(),-1,0);
			}
		}
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#getCountsByScoreLevelAndProductId(java.lang.Integer)
	 */
	public Integer[] getCountsByScoreLevelAndProductId(Integer productId){
		return productReviewDao.getCountsByScoreLevelAndProductId(productId);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#getCountsByScoreSpanAndProductId(java.lang.Integer)
	 */
	public Integer[] getCountsByScoreSpanAndProductId(Integer productId){
		return productReviewDao.getCountsByScoreSpanAndProductId(productId);
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#getCountsOfCustomer(java.lang.Integer)
	 */
	public Integer[] getCountsOfCustomer(Integer customerId){
		return productReviewDao.getCountsOfCustomer(customerId);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#getSearchCriteria(com.probiz.estore.product.model.ProductReviewSearchCriteria, com.probiz.estore.core.search.SearchCriteria)
	 */
	public SearchCriteria getSearchCriteria(ProductReviewSearchCriteria productReviewSearchCriteria, SearchCriteria searchCriteria){
		return productReviewDao.getSearchCriteria(productReviewSearchCriteria, searchCriteria);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#searchByCriteria(com.probiz.estore.product.model.ProductReviewSearchCriteria, com.probiz.estore.core.search.SearchCriteria)
	 */
	public List<ProductReview> searchByCriteria(ProductReviewSearchCriteria productReviewSearchCriteria, SearchCriteria searchCriteria){
		return productReviewDao.searchByCriteria(productReviewSearchCriteria, searchCriteria);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#searchByCriteriaForController(com.probiz.estore.product.model.ProductReviewSearchCriteria, com.probiz.estore.core.search.SearchCriteria)
	 */
	public List<ProductReview> searchByCriteriaForController(ProductReviewSearchCriteria productReviewSearchCriteria, SearchCriteria searchCriteria){
		if (searchCriteria.getPageNo() < 1)  //如果是翻页过前，就拿第一页就可以。
        {
            searchCriteria.changePaging(1, searchCriteria.getPageSize());
        }
	    List<ProductReview> result = searchByCriteria(productReviewSearchCriteria, searchCriteria);
	    if (result == null|| result.size() == 0 )
	    {
	        if (searchCriteria.getPageNo() > searchCriteria.getTotalPageCount()) //如果是翻页前，就拿最后一页就可以。
	        {
	            searchCriteria.changePaging(searchCriteria.getTotalPageCount(), searchCriteria.getPageSize());
	            result = searchByCriteria(productReviewSearchCriteria, searchCriteria);
	        }
	    }
		return result;
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#doMarkRead(com.probiz.estore.common.model.product.ProductReview)
	 */
	public void doMarkRead(ProductReview productReview){
		productReview.setIsRead(ProductReview.STATUS_READ);
		save(productReview);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#doMarkUnRead(com.probiz.estore.common.model.product.ProductReview)
	 */
	public void doMarkUnRead(ProductReview productReview){
		productReview.setIsRead(ProductReview.STATUS_UNREAD);
		save(productReview);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#doMarkShow(com.probiz.estore.common.model.product.ProductReview)
	 */
    public void doMarkShow(ProductReview productReview){
    	Short preStatus = productReview.getStatus().shortValue();
    	productReview.setStatus(ProductReview.STATUS_SHOW);
    	save(productReview);
    	if(productReview.getParent() == null){
			//case:评论
			if(!preStatus.equals(ProductReview.STATUS_SHOW)){
				updateReviewCountAndScore(productReview.getProductId(),0,1);
			}
		}else{
			//case:回复
			if(!preStatus.equals(ProductReview.STATUS_SHOW)){
				updateReviewReplyCount(productReview.getParent(),0,1);
			}
		}
    }
    
    /*
     * (non-Javadoc)
     * @see com.probiz.estore.product.service.ProductReviewManager#doMarkUnShow(com.probiz.estore.common.model.product.ProductReview)
     */
    public void doMarkUnShow(ProductReview productReview){
    	Short preStatus = productReview.getStatus().shortValue();
    	productReview.setStatus(ProductReview.STATUS_UNSHOW);
    	save(productReview);
    	if(productReview.getParent() == null){
			//case:评论
			if(!preStatus.equals(ProductReview.STATUS_UNSHOW)){
				updateReviewCountAndScore(productReview.getProductId(),0,-1);
			}
		}else{
			//case:回复
			if(!preStatus.equals(ProductReview.STATUS_UNSHOW)){
				updateReviewReplyCount(productReview.getParent(),0,-1);
			}
		}
    }
    
    /*
     * (non-Javadoc)
     * @see com.probiz.estore.product.service.ProductReviewManager#doMarkTop(com.probiz.estore.common.model.product.ProductReview)
     */
    public void doMarkTop(ProductReview productReview){
    	productReview.setSortOrder(ProductReview.STATUS_TOP);
		save(productReview);
    }
    /*
     * (non-Javadoc)
     * @see com.probiz.estore.product.service.ProductReviewManager#doMarkUnTop(com.probiz.estore.common.model.product.ProductReview)
     */
    public void doMarkUnTop(ProductReview productReview){
    	productReview.setSortOrder(ProductReview.STATUS_UNTOP);
		save(productReview);
    }

    /*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#addReply(com.probiz.estore.common.model.product.ProductReview)
	 */
	public void addReply(ProductReview reply){
		if(reply.getProductReviewId() == null){
			//默认情况： 新增回复必定可见
			updateReviewReplyCount(reply.getParent(),1,1);
		}
		productReviewDao.save(reply);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#addReview(com.probiz.estore.common.model.product.ProductReview)
	 */
	public void addReview(ProductReview productReview){
		if(productReview.getProductReviewId() != null){
			return;
		}
		//首先获取最先评价的客户id，否则后面更新了就不准确了。
		List<Integer> customerIdList = this.getPreviousCustomerIdListByProductIdBySize(productReview.getProductId(),ConfigUtil.getInstance().getAddReviewFrontMans());
		
		productReviewDao.save(productReview);
		this.productReviewDao.flush();//马上提交，否则后面统计不准确。
		
		//默认情况： 新增评论必定可见
		updateReviewCountAndScore(productReview.getProductId(),1,1);
		
		if(ConfigUtil.getInstance().getCustomerReviewRight().intValue() == ProductReview.REVIEW_RIGHT_BUYBEFORE.intValue() && productReview.getCustomer()!=null){
			//系统设定购买此商品才可评论的则需要对评论资质次数-1
			ReviewEligibility reviewEligibility =  reviewEligibilityDao.getReviewEligibilityByPCustomerIdAndProductId(productReview.getCustomer().getAppuserId(), productReview.getProductId());
			reviewEligibility.setRemainedCount(reviewEligibility.getRemainedCount()-1);
			reviewEligibilityDao.save(reviewEligibility);
		}
		
		this.productReviewDao.flush();//马上提交，否则后面统计不准确。
		//--------start:发表评论获赠积分---------------
		if(ConfigUtil.getInstance().getAddReviewFrontMans() >customerIdList.size()){
			if(null != productReview.getCustomerId() && !customerIdList.contains(productReview.getCustomerId())){
				Customer customer = customerManager.getByAppUserId(productReview.getCustomerId());
				shopPointManager.updateShopPoint(customer, ConfigUtil.getInstance().getAddReviewShopPointAmount(), ShopPoint.TYPE_REVIEW	, productReview);
			}
		}
		//--------end:  发表评论获赠积分---------------
		
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#updateReviewReplyCount(com.probiz.estore.common.model.product.ProductReview, java.lang.Integer, java.lang.Integer)
	 */
	public void updateReviewReplyCount(ProductReview productReview,Integer replyCount, Integer onShowReplyCount){
		if(productReview == null)return;
		productReview.setReplyCount(productReview.getReplyCount().intValue()+replyCount.intValue());
		productReview.setOnShowReplyCount(productReview.getOnShowReplyCount().intValue()+onShowReplyCount.intValue());
		this.save(productReview);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#updateReviewCountAndScore(java.lang.Integer, java.lang.Integer, java.lang.Integer)
	 */
	public void updateReviewCountAndScore(Integer productId,Integer reviewCount, Integer onShowReviewCount){
		Product product = productManager.getById(productId);
		ProductStat stat = product.getProductStat();
		stat.setReviewCount(stat.getReviewCount().intValue() + reviewCount);
		stat.setOnShowReviewCount(stat.getOnShowReviewCount().intValue() + onShowReviewCount);
		stat.setReviewScore(this.getReviewScoreByProductId(productId));
		productStatManager.save(stat);
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#getReviewScoreByProductId(java.lang.Integer)
	 */
	public BigDecimal getReviewScoreByProductId(Integer productId){
		return productReviewDao.getReviewScoreByProductId(productId);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#getOnShowReplyListByReviewId(java.lang.Integer)
	 */
	public List<ProductReview> getOnShowReplyListByReviewId(Integer productReviewId){
		return productReviewDao.getOnShowReplyListByReviewId(productReviewId);
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#countProductReviewTotal()
	 */
	public Long countProductReviewTotal(){
		return productReviewDao.countProductReviewTotal();
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#getPreviousCustomerIdListByProductIdBySize(java.lang.Integer, java.lang.Integer)
	 */
	public List<Integer> getPreviousCustomerIdListByProductIdBySize(Integer productId,Integer size){
		return productReviewDao.getPreviousCustomerIdListByProductIdBySize(productId, size);
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#getReplyCountByProductReviewId(java.lang.Integer)
	 */
	public Long getReplyCountByProductReviewId(Integer productReviewId){
		return productReviewDao.getReplyCountByProductReviewId(productReviewId);
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#getOnShowReplyCountByProductReviewId(java.lang.Integer)
	 */
	public Long getOnShowReplyCountByProductReviewId(Integer productReviewId){
		return productReviewDao.getOnShowReplyCountByProductReviewId(productReviewId);
	}

	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#getReviewCountByProductId(java.lang.Integer)
	 */
	public Long getReviewCountByProductId(Integer productId){
		return productReviewDao.getReviewCountByProductId(productId);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.product.service.ProductReviewManager#getOnShowReviewCountByProductId(java.lang.Integer)
	 */
	public Long getOnShowReviewCountByProductId(Integer productId){
		return productReviewDao.getOnShowReviewCountByProductId(productId);
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#preDelete(java.lang.Object)
	 */
	@Override
	protected void preDelete(ProductReview entity) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#preSave(java.lang.Object)
	 */
	@Override
	protected void preSave(ProductReview entity) {
	}

	
	



}
